Módulo 2: Introdução à Lib Pandas


Tutorial

Imports para a Aula


In [ ]:
import numpy as np
import pandas as pd

Construção

Series


In [ ]:
""" Construtor padrão """
pd.Series(
    name="Compras",
    index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"],  
    data=[2, 12, 1, 5, 2]
)

In [ ]:
""" Construtor padrão: dados desconhecidos """
pd.Series(
    name="Compras",
    index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"]
)

In [ ]:
""" Construtor padrão: valor padrão """
pd.Series(
    name="Compras",
    index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"],
    data="fill here"
)

In [ ]:
""" Recebendo um Dicionário"""
s = pd.Series({"Leite": 2, "Ovos": 12, "Carne": 1, "Arroz": 5, "Feijão": 2})
s.name = "Compras"
s

In [ ]:
""" Recebendo uma Lista"""
s = pd.Series([2, 12, 1, 5, 2])
s

In [ ]:
""" editando parâmetros"""
s.name="Compras"
s.index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"]
s

In [ ]:
""" Ordenação: Índices """
s.sort_index()

In [ ]:
""" Ordenação: Dados """
s.sort_values(ascending=False)

DataFrame


In [ ]:
""" Construtor padrão """
pd.DataFrame(
    index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"],
    columns=["quantidade", "unidade"],
    data=[
        [ 2,  "L"],
        [12, "Ud"], 
        [ 1, "Kg"],
        [ 5, "Kg"], 
        [ 2, "Kg"]
    ]
)

In [ ]:
""" Construtor padrão: dados desconhecidos """
pd.DataFrame(
    index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"],
    columns=["quantidade", "unidade"]
)

In [ ]:
""" Construtor padrão: valor padrão """
pd.DataFrame(
    index=["Leite", "Ovos", "Carne", "Arroz", "Feijão"],
    columns=["quantidade", "unidade"],
    data="?"
)

In [ ]:
""" Recebendo um Dicionário"""
pd.DataFrame(
    {
        "quantidade": {
            "Leite": 2, 
            "Ovos": 12, 
            "Carne": 1, 
            "Arroz": 5, 
            "Feijão": 2
        },
        "unidade": {
            "Leite": "L", 
            "Ovos": "Ud", 
            "Carne": "Kg", 
            "Arroz": "Kg", 
            "Feijão": "Kg"
        }
    }
)

In [ ]:
""" Recebendo um Dicionário de Series"""
index = ["Leite", "Ovos", "Carne", "Arroz", "Feijão"]
pd.DataFrame(
    {
        "quantidade": pd.Series(index=index,  data=[2, 12, 1, 5, 2]),
        "unidade": pd.Series(index=index,  data=["L", "Ud", "Kg", "Kg", "Kg"])
    }
)

In [ ]:
""" Recebendo um vetor de Series"""
index = ["Leite", "Ovos", "Carne", "Arroz", "Feijão"]
df = pd.DataFrame(
    [
        pd.Series(name="quantidade", index=index,  data=[2, 12, 1, 5, 2]),
        pd.Series(name="unidade", index=index,  data=["L", "Ud", "Kg", "Kg", "Kg"])
    ]
)
df

In [ ]:
""" Transpondo para ajustar a Tabela """
df = df.T
df

In [ ]:
""" editando parâmetros"""
df.index = ["Leite tipo A", "Ovos Orgânicos", "Patinho", "Arroz Arbóreo", "Feijão Preto"]
df.columns = ["Quantidade", "Unidade"]
df

In [ ]:
""" Ordenação: Índices """
df.sort_index()

In [ ]:
""" Ordenação: Dados """
df.sort_values(by="Unidade", ascending=False)

Acessando valores

Definição das Variáveis


In [ ]:
index = pd.Index(data=["Leite", "Ovos", "Carne", "Arroz", "Feijão"], name="Itens")
index

In [ ]:
sq = pd.Series(index=index,  data=[2, 12, 1, 5, 2]).sort_values()
sq

In [ ]:
su = pd.Series(index=index,  data=["L", "Ud", "Kg", "Kg", "Kg"]).sort_index()
su

In [ ]:
df = pd.DataFrame({"Quantidade": sq, "Unidade": su}).sort_values(by="Unidade")
df

In [ ]:
df["Preço p/ Ud"] = [5.00, 29.99, 6.50, 3.30, 0.50]
df["Preço Total"] = [25.00, 29.99, 13.00, 6.60, 6.00]
df

Slicing

Series


In [ ]:
sq

In [ ]:
sq[2]

In [ ]:
sq[5:2:-1]

In [ ]:
sq["Leite"]

In [ ]:
sq["Leite":"Arroz"]

DataFrame


In [ ]:
df

In [ ]:
df["Unidade"]

In [ ]:
df.Quantidade

In [ ]:
""" Uma Coluna do DataFrame é uma Series"""
df["Preço Total"][2]

In [ ]:
""" Acesso a mais de uma Coluna """
df[["Preço Total", "Quantidade"]]

In [ ]:
""" acesso às Linhas: método 'loc' """
df.loc["Leite"]

In [ ]:
""" acesso ao item: método 'loc' """
df.loc["Ovos", "Preço Total"]

In [ ]:
""" acesso ao item: método 'iloc' """
df.iloc[4, 3]

In [ ]:
""" acesso por slice: método 'loc' """
df.loc["Leite":, "Preço p/ Ud":]

In [ ]:
""" acesso por slice: método 'iloc' """
df.iloc[3:, 2:]
* Atribuição de Valores em DataFrames

In [ ]:
""" Atribuir Valores em 'slices' levanta warnings """
df["Unidade"][[0, 2]] = "Pacote"
df

In [ ]:
""" Deve-se usar 'loc' ou 'iloc' """
df.loc["Carne", "Unidade"] = "Kilograma"
df.iloc[3, 1] = "Litro"
df

Masks

Conceito


In [ ]:
""" mask => array de bool """
sq > 2

In [ ]:
""" mask => array de bool """
df > 2

Aplicação

* Series

In [ ]:
""" atribuição de valores em uma cópia """
s_tmp = sq.copy()
s_tmp

In [ ]:
s_tmp[s_tmp == 2]

In [ ]:
s_tmp[s_tmp == 2] = 3
s_tmp
* DataFame

In [ ]:
""" atribuição de valores em uma cópia """
df_tmp = df[["Preço p/ Ud", "Preço Total"]].copy()
df_tmp

In [ ]:
""" mask """
mask = (df_tmp > 5) & (df_tmp < 10)
mask

In [ ]:
df_tmp[mask]

In [ ]:
tmp2 = df_tmp.copy()
tmp2[mask] = "?"
tmp2

In [ ]:
s_tmp[s_tmp == 2] = 3
s_tmp

Operações Vetoriais

Definição das Variáveis


In [ ]:
df = pd.DataFrame(
    index=pd.Index(data=["Leite", "Ovos", "Carne", "Arroz", "Feijão"], name="Itens"),
    columns=["Unidade", "Quantidade",  "Preço Unitário"],
    data=np.array([
        ["Litro", "Dúzia", "Kilograma", "Kilograma", "Kilograma"],
        [4, 3, 1, 5, 2],
        [3.00, 6.50, 25.90, 5.00, 3.80]
    ]).T,
)
df

In [ ]:
""" verificando dtypes """
df.dtypes

In [ ]:
"""Conversão necessária pois o pandas interp´reta 'mixed types' como strings """
df[["Quantidade",  "Preço Unitário"]] = df[["Quantidade",  "Preço Unitário"]].astype(float)
df

In [ ]:
""" verificando dtypes """
df.dtypes

Manipulações Numéricas

* Incrementando o Preço Unitário

In [ ]:
df["Preço Unitário"] += 1.
df
* Desconto de 10% no Preço Unitário

In [ ]:
df["Preço Unitário"] *= 0.90
df
* Cálculo do Preço Total por Item

In [ ]:
df["Preço Total"] = df["Preço Unitário"] * df["Quantidade"]
df
* Cálculo do Preço por Kg

In [ ]:
df["Preço Médio Por Kg"] = np.nan
df

In [ ]:
mask = df["Unidade"] == "Kilograma"
df[mask]

In [ ]:
df.loc[mask, "Preço Médio Por Kg"] = (df.loc[mask, "Preço Unitário"] / df.loc[mask, "Quantidade"]).sum()
df
* Preenchendo NaNs

In [ ]:
df.fillna(0)
* Soma : apenas valores numéricos

In [ ]:
df.sum()
* Média: apenas valores numéricos

In [ ]:
df.mean()
* Desvio Padrão: apenas valores numéricos

In [ ]:
df.std()
* Mediana: apenas valores numéricos

In [ ]:
df.median()
* Moda (valores mais frequentes): todos os tipos de valores

In [ ]:
df.mode()

Análise de Dados

Definição das Variáveis


In [ ]:
cols=["c1", "c2", "c3", "c4", "c5"]
data = np.random.rand(100, 5) 
data *= np.array([ 10,  20,  30,  40,  50]) 
data += np.array([100, 200, 300, 400, 500])
data = np.ceil(data)
df = pd.DataFrame(columns=cols, data=data)
df.head(10)

Descrição dos dados


In [ ]:
""" descrevendo as distribuições dos dados """
df.describe()

In [ ]:
""" mesma coisa, manipulando os percentis  """
df.describe(percentiles=[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])

In [ ]:
""" Verificando os valores únicos de C3 """
df.c3.unique()

In [ ]:
""" Verificando a frequencia dos valores únicos de C3 """
df.c3.value_counts()

Desafio 1

Objetivo:

Analisar como Outliers deformam um a distribuição normal.

Configurações


In [ ]:
""" Não altere esse valor, pois ele permite que toda a geração aleatória seja igual para todos """
np.random.seed(123456789)

Dataset Original

O dataset original é uma Series com 1000 elementos cujos dados pertençam a uma distribuição normal de média igual a 150 e desvio padrão 10.

Construção: a função np.random.randn é usada para gerar a distribuição normal, para depois transformá-la com a média e o sigma dados.


In [ ]:
""" Dataset Original, já criado para a solução """
media = 150
sigma = 10
serie = pd.Series(np.random.randn(1000)) * sigma + media

O Acumulador

O acumulador é um DataFrame usado para acumular as transformações feitas em cima do dataset original. Cada transformação será armazenada em uma coluna cujo nome descreve a transformação feita sobre os dados.

Insira o dataset criado na coluna de nome original.


In [ ]:
accum = pd.DataFrame(
    index=range(2600),
    columns=["original"],
    data=serie
)
accum.head().append(accum.tail())

Inserção de dados

Para cada item a seguir, crie um dataset de distribuição normal contendo N elementos, usando a média e o sigma também fornecidos pelo item.

Em seguida, concatene os novos elementos gerados à Series original usando o código abaixo:

series_original = series_original.append(nova_series).reset_index(drop=True)

Depois disso, insira a Series atualizada no acumulador em uma coluna com o nome de coluna fornecido em cada item.

[ A ] Elementos da mesma Distribuição

  • N = 300
  • média = 150
  • sigma = 10
  • coluna = "mesma_distribuição"

In [ ]:
""" Escreva a a Solução Aqui """

[ B ] Elementos de outra distribuição

  • N = 100
  • média = 400
  • sigma = 100
  • coluna = "outliers_adicionados"

In [ ]:
""" Escreva a a Solução Aqui """

[ C ] Elementos Próximos à média

  • N = 1000
  • média = 150
  • sigma = 0.1
  • coluna = "elementos_prox_a_media"

In [ ]:
""" Escreva a a Solução Aqui """

Avaliação das Séries:

Avaliar o acumulador e verificar o que mudou na distribuição original.


In [ ]:
""" Escreva a a Solução Aqui """

Desafio 2

Objetivo:

Implementar o OneHotEncoding, método muito utilizado em Machine Learning para codificar dados categóricos na forma em que algoritmos de aprendizado de máquina compreendam.

Exemplo:

original = pd.Series([
    "classe_1",
    "classe_1",
    "classe_2",
    "classe_2",
    "classe_1",
    "classe_2",
])

# --- 

encoded = pd.DataFrame(
    columns=["classe_1", "classe_2"],
    data=[
        [1, 0],
        [1, 0],
        [0, 1],
        [0, 1],
        [1, 0],
        [0, 1]
    ]

)

Série Original:


In [ ]:
classes = ["Leite", "Ovos", "Carne", "Arroz", "Feijão"]
labels = pd.Series(np.random.choice(classes, 100))

Dataset Codificado:


In [ ]:
""" Escreva a a Solução Aqui """